package com.at.service.impl;

import com.at.dao.BolgDao;
import com.at.domain.Blog;
import com.at.domain.BlogQuery;
import com.at.domain.Type;
import com.at.exception.NotFoundException;
import com.at.service.BlogService;
import com.at.util.MarkdownUtils;
import com.at.util.MyBeanUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import javax.transaction.Transactional;;
import java.util.*;

/**
 * @author : code1997
 * @date :2020-09-2020/9/28 9:13
 */
@Service
public class BlogServiceImpl implements BlogService {

    @Autowired
    private BolgDao bolgDao;

    @Override
    public Blog getBolg(Long id) {
        return bolgDao.getOne(id);
    }

    @Transactional
    @Override
    public Blog getBolgAndConvert(Long id) {
        Blog blog = bolgDao.getOne(id);
        if (blog==null){
            throw new NotFoundException("该博客不存在！");
        }
        //防止类似于hibernate的缓存的影响
        Blog temp=new Blog();
        BeanUtils.copyProperties(blog, temp);
        String content=blog.getContent();
        /*将markdown文本转换为html*/
        temp.setContent(MarkdownUtils.markdownToHtmlExtensions(content));
        bolgDao.updateViews(id);
        return temp;
    }

    @Override
    public Page<Blog> listBlog(Pageable pageable, BlogQuery blog) {
        /*条件查询:实现接口JpaSpecificationExecutor*/
        return bolgDao.findAll((Specification<Blog>) (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates=new ArrayList<>();
            /*查询条件的构建*/
            if (blog.getTitle()!=null&&blog.getTitle().trim().length()!=0){
                predicates.add(criteriaBuilder.<String>like(root.get("title"), blog.getTitle()));
            }
            if (blog.getTypeId()!=null){
                predicates.add(criteriaBuilder.<Type>equal(root.get("type").get("id"), blog.getTypeId()));
            }
            if(blog.isRecommend()){
                predicates.add(criteriaBuilder.<Boolean>equal(root.get("recommend"), blog.isRecommend()));
            }
            /*添加查询条件，并进行查询*/
            criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
            return null;
        },pageable);
    }
    @Override
    public Page<Blog> listBlog(Pageable pageable) {

        return bolgDao.findAll(pageable);
    }

    @Override
    public Page<Blog> listBlogByTagId(Pageable pageable, Long tagId) {

        return bolgDao.findAll((Specification<Blog>) (root, criteriaQuery, criteriaBuilder) -> {
            Join tags = root.join("tags");
            return criteriaBuilder.equal(tags.get("id"),tagId);
        },pageable);
    }

    @Override
    public Page<Blog> listBlogByQuery(Pageable pageable, String query) {

        return bolgDao.findByQuery("%"+query+"%", pageable);
    }

    @Override
    public List<Blog> listRecommedBlogTop(Integer size) {
        Sort sort = Sort.by(Sort.Direction.DESC,"updateTime");
        Pageable pageable = PageRequest.of(0,size, sort);
        return bolgDao.getTop(pageable);
    }

    @Transactional
    @Override
    public Blog saveBlog(Blog blog) {
        if (blog.getId()==null){
            blog.setCreateTime(new Date());
            blog.setUpdateTime(new Date());
            blog.setViews(0);
        }else {
            blog.setUpdateTime(new Date());
        }
        return bolgDao.save(blog);
    }

    @Transactional
    @Override
    public Blog updateBlog(Long id, Blog blog) {
        Optional<Blog> byId = bolgDao.findById(id);
        if (!byId.isPresent()){
            throw new NotFoundException("不存在该博客");
        }
        Blog tempBlog = byId.get();
        BeanUtils.copyProperties(blog, tempBlog, MyBeanUtils.getNUllPropertyNames(blog));
        tempBlog.setUpdateTime(new Date());
        return bolgDao.save(tempBlog);
    }

    @Override
    public void deleteBlog(Long id) {
        bolgDao.deleteById(id);
    }

    @Override
    public Map<String, List<Blog>> archivesBlog() {
        //1.获取全部的年份
        List<String> groupYear = bolgDao.findGroupYear();
        //2.根据年份分组获取所有的博客信息
        Map<String,List<Blog>> blogs=new TreeMap<>((o1, o2) -> -o1.compareTo(o2));
        System.out.println(groupYear);
        for (String s : groupYear) {
            blogs.put(s,bolgDao.findByYear(s));
        }

        return blogs;
    }

    @Override
    public Long getBlogCount() {
        return bolgDao.count();
    }
}
